/**
 * Driver - Main function to create and run the scale functionality.
 * 
 * CS575 Software Design
 * Group 6
 * Group Members: Anthony Davidson, Kendra Scheesley, Lyndsey Whitman, Stephen Zakrewsky
 * Date: May 19, 2012
 * Main Author(s): Anthony Davidson, Lyndsey Whitman
 * 
 * Modified: 6/1 Stephen Zakrewsky
 */

package edu.drexel.cs575.a3;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Driver
{
	public static void main(String[] args)
	{
		UserInputCollector userInputCollector;

		// Get the scale factory
		ScaleFactory scaleFactory = ScaleFactory.getInstance();

		// Create the scale
		Scale scale = scaleFactory.createScale(190);

		// Tare the scale to make sure it is set to zero
		scale.tare();

		Scanner inputFileScanner = null;
		try
		{
			inputFileScanner = new Scanner(new File(".itemLists"));

			while (inputFileScanner.hasNextLine())
			{
				String itemLine = inputFileScanner.nextLine();
				String[] itemArray = itemLine.split(",");
				if (itemArray.length == 0)
				{
					throw new IllegalStateException(
							"File .itemLists invalid format");
				}

				String inputFile = itemArray[0];
				String outputFile = itemArray[1];

				userInputCollector = getInputCollectorForFile(inputFile);

				// Set the Scale's Bill object with the output file
				scale.setBillOutputStream(new FileOutputStream(outputFile));

				//set the output to the Bill, making sure it's not outputting 
				//to the display
				scale.setOutput(scale.getBill());

				// Map to hold like items together.
				Map<String, WeighableItems> weighableItemComposites = new HashMap<String, WeighableItems>();

				// Loop through all items in the list and print the weight and
				// price for each one.
				while (userInputCollector.hasNextItem())
				{
					// Get the next item in the list
					WeighableItem item = userInputCollector.getNextItem();

					// check map for item
					WeighableItems composite = weighableItemComposites.get(item.getName());

					if (composite != null)
					{
						// item already exists so add to the collection
						composite.add(item);
					} else
					{
						// First item is in list so create a new composite and
						// add to map
						composite = new WeighableItems((item.getName()));
						composite.add(item);
						weighableItemComposites.put(item.getName(), composite);
					}
				}

				// Loop through all the collections of the items and print their
				// total price
				double totalBillPrice = 0.0;
				
				for (Map.Entry<String, WeighableItems> e : weighableItemComposites.entrySet())
				{
					// add item to the scale to get the total weight and price
					scale.addItem(e.getValue());
					// clear the scale
					scale.removeItem(e.getValue());
					
					totalBillPrice += e.getValue().calculatePricePerMassUnit();
				}

				// Calculate Tax
				CalculateTax taxCalc = new Tax();
				
				double taxTotal = taxCalc.calculateTax(totalBillPrice);
				
				scale.setBill(new SubTotalFooter(scale.getBill(), totalBillPrice));
				scale.setBill(new TotalTaxFooter(scale.getBill(), taxTotal));
				scale.setBill(new TotalFooter(scale.getBill(), (totalBillPrice + taxTotal)));
				scale.setBill(new ThankYouFooter(scale.getBill()));
				scale.setBill(new DateHeader(scale.getBill()));
				scale.setBill(new LocaleHeader(scale.getBill()));
				
				scale.getBill().printBill();
			}
		} catch (Exception e)
		{
			System.out.println("Sorry, an error occurred.");
			e.printStackTrace();
			System.exit(1);
		}
	}

	private static UserInputCollector getInputCollectorForFile(String inputFile)
			throws IOException
	{
		UserInputCollector userInputCollector = null;
		BufferedReader in = new BufferedReader(new FileReader(inputFile));
		try
		{
			String firstLine = in.readLine();
			if (firstLine != null)
			{
				String[] fields = firstLine.split(",");
				if (fields.length == 4)
				{
					userInputCollector = new FourColumnFileInput(inputFile);
				}
			}
		} finally
		{
			try
			{
				in.close();
			} catch (Exception e)
			{
				// Don't mask the original exception.
			}
		}

		if (userInputCollector == null)
		{
			userInputCollector = new ThreeColumnFileInput(inputFile);
		}

		return userInputCollector;
	}

}
